#include<bits/stdc++.h>
#define MAXN 100005
using namespace std;
inline int read(){
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-48;
        ch=getchar();
    }
    return x*f;
}
int T,n,m,L,V,d[MAXN],v[MAXN],a[MAXN],p[MAXN];
struct _clh{
    int l,r;
}clh[MAXN];
struct _zxn{
    bool chk;
    int l,r;
}zxn[MAXN];
bool cmp(_zxn x,_zxn y){
    return x.r<y.r;
}
int main(){
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    T=read();
    while(T--){
        n=read(),m=read(),L=read(),V=read();
        for(int i=1;i<=n;i++){
            d[i]=read(),v[i]=read(),a[i]=read();
            if(a[i]>0){
                if(v[i]>V) clh[i].l=d[i],clh[i].r=L;//("[%d,%d]\n",d[i],L);
                else{
                    int x=(V*V-v[i]*v[i])/(2*a[i])+d[i]+1;
                    if(x<=L) clh[i].l=x,clh[i].r=L;//printf("[%d,%d]\n",x,L);
                    else clh[i].l=INT_MAX,clh[i].r=INT_MAX;//("impossible\n");
                }
            }
            if(a[i]==0){
                if(v[i]>V) clh[i].l=d[i],clh[i].r=L;//printf("[%d,%d]\n",d[i],L);
                else clh[i].l=INT_MAX,clh[i].r=INT_MAX;//printf("impossible\n");
            }
            if(a[i]<0){
                if(v[i]<=V) clh[i].l=INT_MAX,clh[i].r=INT_MAX;//printf("impossible\n");
                else{
                    int x=(V*V-v[i]*v[i])/(2*a[i])+d[i]-((V*V-v[i]*v[i])%(2*a[i])==0);
                    x=min(x,min(v[i]*v[i]/(-2*a[i])+d[i],L));
                    clh[i].l=d[i],clh[i].r=x;//printf("[%d,%d]\n",d[i],x);
                }
            }
        }
        for(int i=1;i<=m;i++) p[i]=read();
        sort(p+1,p+m+1);
        int ans1=0;
        for(int i=1;i<=n;i++){
            int pos1=lower_bound(p+1,p+m+1,clh[i].l)-p;
            int pos2=upper_bound(p+1,p+m+1,clh[i].r)-p-1;
            if(pos1<=pos2) ans1++,zxn[i].chk=true;
            else zxn[i].chk=false;
            zxn[i].l=pos1,zxn[i].r=pos2;
            // printf("%d %d\n",pos1,pos2);
        }
        printf("%d ",ans1);
        sort(zxn+1,zxn+n+1,cmp);
        int ans2=0,now_pos=INT_MAX;
        for(int i=1;i<=n;i++){
            if(!zxn[i].chk) continue;
            if(!(now_pos>=zxn[i].l&&now_pos<=zxn[i].r)) ans2++,now_pos=zxn[i].r;
        }
        ans2=m-ans2;
        printf("%d\n",ans2);
    }
    return 0;
}